home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-11-08 | 15.9 KB | 522 lines | [TEXT/MPS ] |
- //========================================================================================
- //
- // File: FWLnkMgr.cpp
- // Release Version: $ 1.0d11 $
- //
- // Copyright: © 1995 by Apple Computer, Inc., all rights reserved.
- //
- //========================================================================================
-
- #include "FWFrameW.hpp"
-
- #ifndef FWLNKMGR_H
- #include "FWLnkMgr.h"
- #endif
-
- // ----- Framework Includes -----
-
- #ifndef FWPART_H
- #include "FWPart.h"
- #endif
-
- #ifndef FWPRESEN_H
- #include "FWPresen.h"
- #endif
-
- #ifndef FWITERS_H
- #include "FWIters.h"
- #endif
-
- #ifndef FWUTIL_H
- #include "FWUtil.h"
- #endif
-
- // ----- Foundation Includes -----
-
- #ifndef FWPRIDEB_H
- #include "FWPriDeb.h"
- #endif
-
- #ifndef FWMEMMGR_H
- #include "FWMemMgr.h"
- #endif
-
- // ----- OS Includes -----
-
- #ifndef FWTIME_H
- #include "FWTime.h"
- #endif
-
- // ----- OpenDoc Includes -----
-
- #ifndef SOM_Module_OpenDoc_StdProps_defined
- #include <StdProps.xh>
- #endif
-
- #ifndef SOM_Module_OpenDoc_StdTypes_defined
- #include <StdTypes.xh>
- #endif
-
- #ifndef SOM_ODStorageUnit_xh
- #include <StorageU.xh>
- #endif
-
- #ifndef SOM_ODSession_xh
- #include <ODSessn.xh>
- #endif
-
- #ifndef SOM_ODDraft_xh
- #include <Draft.xh>
- #endif
-
- #ifndef SOM_ODClipboard_xh
- #include <Clipbd.xh>
- #endif
-
- #ifndef SOM_ODLink_xh
- #include <Link.xh>
- #endif
-
- #ifndef SOM_ODLinkSpec_xh
- #include <LinkSpec.xh>
- #endif
-
- #ifndef SOM_ODLinkSource_xh
- #include <LinkSrc.xh>
- #endif
-
- //========================================================================================
- // Runtime information
- //========================================================================================
-
- #if FW_LIB_EXPORT_PRAGMAS
- #pragma lib_export on
- #endif
-
- #ifdef FW_BUILD_MAC
- #pragma segment framework
- #endif
-
- FW_DEFINE_CLASS_M0(FW_CLinkManager)
-
- //========================================================================================
- // class FW_CLinkManager
- //========================================================================================
-
- //---------------------------------------------------------------------------------------
- // FW_CLinkManager constructor
- //---------------------------------------------------------------------------------------
-
- FW_CLinkManager::FW_CLinkManager(Environment *ev, FW_CPart* thePart) :
- fPart(thePart),
- fPendingPublishLink(NULL),
- fPendingDropLink(NULL),
- fPublishLinkList(NULL),
- fSubscribeLinkList(NULL)
- {
- }
-
- //---------------------------------------------------------------------------------------
- // FW_CLinkManager destructor
- //---------------------------------------------------------------------------------------
-
- FW_CLinkManager::~FW_CLinkManager()
- {
- delete fSubscribeLinkList;
- fSubscribeLinkList = NULL;
-
- delete fPublishLinkList;
- fPublishLinkList = NULL;
- }
-
- //---------------------------------------------------------------------------------------
- // FW_CLinkManager::RemoveAllLinks
- //---------------------------------------------------------------------------------------
-
- void FW_CLinkManager::RemoveAllLinks(Environment *ev)
- {
- // ----- Delete publishers -----
- if (fPublishLinkList)
- {
- FW_CPublishLink* link;
- while ((link = (FW_CPublishLink*)fPublishLinkList->First()) != NULL)
- {
- fPublishLinkList->Remove(link);
- delete link;
- }
- }
-
- // ----- Delete subscribers -----
- if (fSubscribeLinkList)
- {
- FW_CSubscribeLink* link;
- while ((link = (FW_CSubscribeLink*)fSubscribeLinkList->First()) != NULL)
- {
- fSubscribeLinkList->Remove(link);
- delete link;
- }
- }
- }
-
- //---------------------------------------------------------------------------------------
- // FW_CLinkManager::AddToPublishLinkList
- //---------------------------------------------------------------------------------------
-
- void FW_CLinkManager::AddToPublishLinkList(Environment* ev, FW_CPublishLink* publishLink)
- {
- if (fPublishLinkList == NULL)
- fPublishLinkList = new FW_CPrivOrderedCollection;
-
- fPublishLinkList->AddLast(publishLink);
- }
-
- //---------------------------------------------------------------------------------------
- // FW_CLinkManager::AddToSubscribeLinkList
- //---------------------------------------------------------------------------------------
-
- void FW_CLinkManager::AddToSubscribeLinkList(Environment* ev, FW_CSubscribeLink* subscribeLink)
- {
- if (fSubscribeLinkList == NULL)
- fSubscribeLinkList = new FW_CPrivOrderedCollection;
-
- fSubscribeLinkList->AddLast(subscribeLink);
- }
-
- //---------------------------------------------------------------------------------------
- // FW_CLinkManager::BreakPublishLink
- //---------------------------------------------------------------------------------------
- void FW_CLinkManager::BreakPublishLink(Environment* ev, FW_CPublishLink* publishLink)
- {
- publishLink->BreakLink(ev);
- this->RemoveFromPublishLinkList(ev, publishLink);
- }
-
- //---------------------------------------------------------------------------------------
- // FW_CLinkManager::BreakSubscribeLink
- //---------------------------------------------------------------------------------------
- void FW_CLinkManager::BreakSubscribeLink(Environment* ev, FW_CSubscribeLink* subscribeLink)
- {
- subscribeLink->BreakLink(ev);
- this->RemoveFromSubscribeLinkList(ev, subscribeLink);
- }
-
- //---------------------------------------------------------------------------------------
- // FW_CLinkManager::CountPublishers
- //---------------------------------------------------------------------------------------
-
- unsigned long FW_CLinkManager::CountPublishers(Environment* ev) const
- {
- if (fPublishLinkList)
- return fPublishLinkList->Count();
-
- return 0;
- }
-
- //---------------------------------------------------------------------------------------
- // FW_CLinkManager::CountSubscribers
- //---------------------------------------------------------------------------------------
-
- unsigned long FW_CLinkManager::CountSubscribers(Environment* ev) const
- {
- if (fSubscribeLinkList)
- return fSubscribeLinkList->Count();
-
- return 0;
- }
-
- //---------------------------------------------------------------------------------------
- // FW_CLinkManager::CreateLink
- //---------------------------------------------------------------------------------------
-
- ODLinkSource* FW_CLinkManager::CreateLink(Environment *ev, ODByteArray* data)
- {
- ODLinkSource* odLinkSource = NULL;
- ODUpdateID updateID = *((ODUpdateID*)(data->_buffer));
-
- // The link spec is either on the clipboard or saved from a Drag&Drop operation.
- // Determine which one to use by checking the ids
-
- // --- Check the clipboard link spec first, since it's the most likely candidate ---
- FW_CPublishLink* pendingPublishLink = this->GetPendingPublish(ev);
- if (pendingPublishLink && (pendingPublishLink->GetPendingID(ev) == updateID))
- {
- // Get the link if it already exists
- odLinkSource = pendingPublishLink->GetODLinkSource(ev);
- }
- else // check for a Drag&Drop link spec
- {
- pendingPublishLink = this->GetPendingDropLink(ev);
- FW_ASSERT(pendingPublishLink != NULL);
- FW_ASSERT(pendingPublishLink->GetPendingID(ev) == updateID);
-
- // The Drag&Drop link spec is only good for creating one link
- this->SetPendingDropLink(ev, NULL);
- }
-
- if (odLinkSource == NULL) // link does not yet exist
- {
- odLinkSource = fPart->GetStorageUnit(ev)->GetDraft(ev)->CreateLinkSource(ev, fPart->GetODPart(ev));
-
- pendingPublishLink->SetODLinkSource(ev, odLinkSource);
- this->AddToPublishLinkList(ev, pendingPublishLink);
- pendingPublishLink->Publish(ev);
- // Don't DeletePendingPublish, because more links may be created from it
- }
- else
- {
- pendingPublishLink->ContentUpdated(ev, kODUnknownUpdate, TRUE);
- odLinkSource->Acquire(ev);
- }
-
- return odLinkSource;
- }
-
- //---------------------------------------------------------------------------------------
- // FW_CLinkManager::DeletePendingPublish
- //---------------------------------------------------------------------------------------
-
- void FW_CLinkManager::DeletePendingPublish(Environment *ev)
- {
- if (fPendingPublishLink != NULL)
- {
- ODClipboard* clipboard = fPart->GetSession(ev)->GetClipboard(ev);
-
- if (fPendingPublishLink->GetPendingID(ev) == clipboard->GetUpdateID(ev))
- {
- ODStorageUnit* clipboardSU = clipboard->GetContentStorageUnit(ev);
- if (clipboardSU->Exists(ev, kODPropLinkSpec, (ODValueType) NULL, 0) == TRUE)
- {
- clipboardSU->Focus(ev, kODPropLinkSpec, kODPosUndefined, (ODValueType) NULL, 0, kODPosUndefined);
- clipboardSU->Remove(ev);
- }
- }
-
- if (fPendingPublishLink->IsPending(ev)) // CreateLink was never called
- delete fPendingPublishLink;
-
- fPendingPublishLink = NULL;
- }
- }
-
- //---------------------------------------------------------------------------------------
- // FW_CLinkManager::DoChangeLinkStatus
- //---------------------------------------------------------------------------------------
-
- void FW_CLinkManager::DoChangeLinkStatus(Environment* ev, ODFrame* odFrame)
- {
- // Embedding parts should override to call ODFrame::ChangeLinkStatus for any
- // embedded frames that are involved in a link when a link is created, broken, moved, etc.
- // odFrame is the frame whose link status has changed.
- }
-
- //---------------------------------------------------------------------------------------
- // FW_CLinkManager::DoUpdateLinks
- //---------------------------------------------------------------------------------------
-
- void FW_CLinkManager::DoUpdateLinks(Environment *ev,
- ODFrame* odEmbeddedFrame,
- ODUpdateID updateID)
- {
- // An embedded frame has changed. (Formerly named EmbeddedFrameUpdated)
- // Embedding parts should override to do the following:
- // 1) If odEmbeddedFrame is involved in one of my link sources, update the link with new data.
- // 2) Call ContentUpdated on display frames as appropriate.
- }
-
- //---------------------------------------------------------------------------------------
- // FW_CLinkManager::EditInLinkAttempted
- //---------------------------------------------------------------------------------------
-
- FW_Boolean FW_CLinkManager::EditInLinkAttempted(Environment *ev, ODFrame* odFrame)
- {
- // Not yet implemented
- return FALSE;
- }
-
- //---------------------------------------------------------------------------------------
- // FW_CLinkManager::ODtoPublishLink
- //---------------------------------------------------------------------------------------
-
- FW_CPublishLink* FW_CLinkManager::ODtoPublishLink(Environment* ev, ODLinkSource* linkSource) const
- {
- FW_COrderedCollectionIterator iter(fPublishLinkList);
- for (FW_CPublishLink* link = (FW_CPublishLink*)iter.First(); iter.IsNotComplete(); link = (FW_CPublishLink*)iter.Next())
- {
- if (linkSource->IsEqualTo(ev, link->GetODLinkSource(ev)))
- return link;
- }
- return NULL;
- }
-
- //---------------------------------------------------------------------------------------
- // FW_CLinkManager::ODtoSubscribeLink
- //---------------------------------------------------------------------------------------
-
- FW_CSubscribeLink* FW_CLinkManager::ODtoSubscribeLink(Environment* ev, ODLink* odLink) const
- {
- FW_COrderedCollectionIterator iter(fSubscribeLinkList);
- for (FW_CSubscribeLink* link = (FW_CSubscribeLink*)iter.First(); iter.IsNotComplete(); link = (FW_CSubscribeLink*)iter.Next())
- {
- if (odLink->IsEqualTo(ev, link->GetODLink(ev)))
- return link;
- }
- return NULL;
- }
-
- //---------------------------------------------------------------------------------------
- // FW_CLinkManager::RevealLink
- //---------------------------------------------------------------------------------------
-
- void FW_CLinkManager::RevealLink(Environment* ev, ODLinkSource* linkSource)
- {
- FW_DEBUG_MESSAGE("RevealLink: Not Yet Implemented");
- }
-
- //---------------------------------------------------------------------------------------
- // FW_CLinkManager::RemoveFromPublishLinkList
- //---------------------------------------------------------------------------------------
-
- void FW_CLinkManager::RemoveFromPublishLinkList(Environment* ev, FW_CPublishLink* publishLink)
- {
- fPublishLinkList->Remove(publishLink);
-
- if (publishLink == fPendingPublishLink)
- this->DeletePendingPublish(ev);
-
- if (fPublishLinkList->Count() == 0)
- {
- delete fPublishLinkList;
- fPublishLinkList = NULL;
- }
- }
-
- //---------------------------------------------------------------------------------------
- // FW_CLinkManager::RemoveFromSubscribeLinkList
- //---------------------------------------------------------------------------------------
-
- void FW_CLinkManager::RemoveFromSubscribeLinkList(Environment* ev, FW_CSubscribeLink* subscribeLink)
- {
- fSubscribeLinkList->Remove(subscribeLink);
-
- if (fSubscribeLinkList->Count() == 0)
- {
- delete fSubscribeLinkList;
- fSubscribeLinkList = NULL;
- }
- }
-
- //---------------------------------------------------------------------------------------
- // FW_CLinkManager::RestorePublishLink
- //---------------------------------------------------------------------------------------
- void FW_CLinkManager::RestorePublishLink(Environment* ev, FW_CPublishLink* publishLink)
- {
- this->AddToPublishLinkList(ev, publishLink);
- publishLink->RestoreLink(ev, fPart);
- publishLink->Publish(ev);
- }
-
- //---------------------------------------------------------------------------------------
- // FW_CLinkManager::RestoreSubscribeLink
- //---------------------------------------------------------------------------------------
- void FW_CLinkManager::RestoreSubscribeLink(Environment* ev, FW_CSubscribeLink* subscribeLink)
- {
- this->AddToSubscribeLinkList(ev, subscribeLink);
- subscribeLink->RestoreLink(ev, fPart);
- subscribeLink->HandleSubscribe(ev);
- }
-
- //---------------------------------------------------------------------------------------
- // FW_CLinkManager::PasteWithLink
- //---------------------------------------------------------------------------------------
- FW_Boolean FW_CLinkManager::PasteWithLink(Environment* ev, ODStorageUnit* storageUnit,
- ODPasteAsResult& pasteAsResult,
- FW_CPresentation* presentation)
- {
- FW_Boolean result = FALSE;
- ODLinkSpec* linkSpec = NULL;
- ODLink* odLink = NULL;
- ODDraft* draft = fPart->GetStorageUnit(ev)->GetDraft(ev);
- if (!storageUnit->Exists(ev, kODPropLinkSpec, (ODValueType)NULL, 0))
- return FALSE;
-
- FW_VOLATILE(result);
- FW_VOLATILE(linkSpec);
- FW_VOLATILE(odLink);
-
- FW_TRY
- {
- linkSpec = draft->CreateLinkSpec(ev, NULL, NULL);
-
- storageUnit->Focus(ev, kODPropLinkSpec, kODPosUndefined, (ODValueType)NULL, 0, kODPosUndefined);
- linkSpec->ReadLinkSpec(ev, storageUnit);
-
- // ---- Establish the Link ----
- odLink = draft->AcquireLink(ev, (ODStorageUnitID)0, linkSpec); // use linkSpec to retrieve the link
-
- if (odLink)
- {
- ODLinkInfo linkInfo;
- linkInfo.change = kODUnknownUpdate; // not yet updated
- FW_CTime time = FW_CTime::GetCurrentTime();
- linkInfo.creationTime = time.GetTime();
- linkInfo.changeTime = linkInfo.creationTime;
- linkInfo.autoUpdate = pasteAsResult.autoUpdateSetting;
-
- unsigned long length = strlen(pasteAsResult.selectedKind);
- linkInfo.kind = (ODValueType)FW_CMemoryManager::AllocateBlock(length+1);
- FW_CMemoryManager::CopyMemory(pasteAsResult.selectedKind, linkInfo.kind, length);
-
- // --- Embed or incorporate the link ---
- this->MakeSubscribeLink(ev, odLink, &linkInfo, presentation);
- result = TRUE;
-
- odLink->Release(ev); // to balance AcquireLink
- }
- }
- FW_CATCH_BEGIN
- FW_CATCH_EVERYTHING()
- {
- if (linkSpec)
- delete linkSpec;
- if (odLink)
- odLink->Release(ev);
- FW_THROW_SAME();
- }
- FW_CATCH_END
-
- if (linkSpec)
- delete linkSpec;
-
- return result;
- }
-
- //---------------------------------------------------------------------------------------
- // FW_CLinkManager::MakeSubscribeLink
- //---------------------------------------------------------------------------------------
- void FW_CLinkManager::MakeSubscribeLink(Environment* ev,
- ODLink* odLink,
- ODLinkInfo* linkInfo,
- FW_CPresentation* presentation)
- {
- FW_CSubscribeLink* subscribeLink = NULL;
- FW_VOLATILE(subscribeLink);
-
- FW_TRY
- {
- subscribeLink = this->NewSubscribeLink(ev, odLink, linkInfo, presentation);
- this->AddToSubscribeLinkList(ev, subscribeLink);
- subscribeLink->Register(ev, fPart); // causes LinkUpdated to be called
- if (subscribeLink->GetUpdateID(ev) != kODUnknownUpdate) // LinkUpdated succeeded
- subscribeLink->HandleSubscribe(ev);
- }
- FW_CATCH_BEGIN
- FW_CATCH_EVERYTHING()
- {
- if (subscribeLink)
- delete subscribeLink;
- FW_THROW_SAME();
- }
- FW_CATCH_END
- }
-
-